package com.lxu.service;

import com.lxu.exceptions.BusinessException;
import com.lxu.model.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

/**
 * 1、方法本身没有配置事务，肯定没有事务功能；springboot自动配置了事务，springmvc要手动配置
 * 2、数据库不支持事务，肯定没有事务功能；比如mysql的MyISAM
 * 3、事务方法是非public，不支持事务；
 * 4、try-catch对事务方法进行了捕获，事务失败；
 * 5、自定义异常不在rollbackFor的范围内，系统默认是Exception和Error，事务失败；
 * 6、事务的传播机制为Propagation.NOT_SUPPORTED、Propagation.NEVER，事务失败；
 * 7、A、B两个方法，A无事务，B有事务，A调用B，事务失败；
 * 8、rollbackFor的异常，不是抛出的异常，事务失败；
 */
@Service
public class UserService {

    @Autowired
    private JdbcTemplate jdbcTemplate;

    /**
     * 无事务   程序异常，数据正常入库
     */
    public  void  saveNoTransaction(){
        jdbcTemplate.update("insert into user(name,passwd,permissions,dept_id) values('徐良','123','333','666')");
        int i=1/0;
    }

    /**
     * 有事务   程序异常，数据入库失败，事务回滚
     */
    @Transactional
    public  void  saveWithTransactional(){
        jdbcTemplate.update("insert into user(name,passwd,permissions,dept_id) values('徐良','123','333','666')");
        int i=1/0;
    }
    // 以下是事务失效场景

    /**
     * try catch 會導致事務回滾失效
     */
    @Transactional
    public  void  saveWithTryCatch(){
        try{
        jdbcTemplate.update("insert into user(name,passwd,permissions,dept_id) values('徐良','123','333','666')");
        int i=1/0;
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    /**
     * try catch 會導致事務回滾 成功
     */
    @Transactional(rollbackFor = Exception.class)
    public  void  saveWithTryCatchAndRollback(){
        try{
            jdbcTemplate.update("insert into user(name,passwd,permissions,dept_id) values('徐良','123','333','666')");
            int i=1/0;
        }catch (Exception e){
            throw  new RuntimeException();
        }
    }

    /**
     * try catch 會導致事務回滾成功
     */
    @Transactional
    public  void  saveWithTryCatchAndThrowRuntimeException(){
        try{
            jdbcTemplate.update("insert into user(name,passwd,permissions,dept_id) values('徐良','123','333','666')");
            int i=1/0;
        }catch (Exception e){
            throw  new RuntimeException();
        }
    }

    /**
     * try catch 自定义异常  回滚失败
     */
    @Transactional
    public  void  saveWithTryCatchAndThrowCustomizeException() throws BusinessException {
        try{
            jdbcTemplate.update("insert into user(name,passwd,permissions,dept_id) values('徐良','123','333','666')");
            int i=1/0;
        }catch (Exception e){
            throw  new BusinessException();
        }
    }

    /**
     * try catch 自定义异常  rollbackFor  回滚成功
     */
    @Transactional(rollbackFor = BusinessException.class)
    public  void  saveWithTryCatchAndThrowCustomizeException2() throws BusinessException {
        try{
            jdbcTemplate.update("insert into user(name,passwd,permissions,dept_id) values('徐良','123','333','666')");
            int i=1/0;
        }catch (Exception e){
            throw  new BusinessException();
        }
    }

    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public  void  saveWithTransactionalAndNotSupport(){
        jdbcTemplate.update("insert into user(name,passwd,permissions,dept_id) values('徐良','123','333','666')");
        int i=1/0;
    }

    @Transactional(propagation = Propagation.NEVER)
    public  void  saveWithTransactionalAndNever(){
        jdbcTemplate.update("insert into user(name,passwd,permissions,dept_id) values('徐良','123','333','666')");
        int i=1/0;
    }

    @Transactional(propagation = Propagation.SUPPORTS)
    public  void  saveWithTransactionalAndSupports(){
        jdbcTemplate.update("insert into user(name,passwd,permissions,dept_id) values('徐良','123','333','666')");
        int i=1/0;
    }


    public  void  saveA(){
        jdbcTemplate.update("insert into user(name,passwd,permissions,dept_id) values('徐良','123','333','666')");
        saveB();
    }
    @Transactional
    public  void  saveB(){
        jdbcTemplate.update("insert into user(name,passwd,permissions,dept_id) values('徐良123','123','333','666')");
        int i=1/0;
    }



    @Transactional(propagation = Propagation.REQUIRED)
    public  void  saveC(){
        jdbcTemplate.update("insert into user(name,passwd,permissions,dept_id) values('徐良','123','333','666')");
        saveD();
        int i=1/0;
    }
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public  void  saveD(){
        jdbcTemplate.update("insert into user(name,passwd,permissions,dept_id) values('徐良123','123','333','666')");
        int i=1/0;
    }

    @Transactional
    protected   void  saveE(){
        jdbcTemplate.update("insert into user(name,passwd,permissions,dept_id) values('徐良123','123','333','666')");
        int i=1/0;
    }

}
